#include "stm32f10x.h"                  // Device header
#include "I2C_Soft.h"
void I2C_WaitEvent(I2C_TypeDef* I2Cx,u32 I2C_EVENT)
{
	int Timeout = 10000;
	while(
		I2C_CheckEvent(I2Cx,I2C_EVENT) != SUCCESS
		&&
		Timeout-- > 0
	); //超时等待
}

void I2C_Periph_Init(void) {
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure; //SCL:B10 SDA:B11
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //复用开漏输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	I2C_InitTypeDef I2C_InitStructure;
	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStructure.I2C_ClockSpeed = 50000;
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//高速模式下占空比为2:1
	I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//默认给应答
	I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//当stm32作为从机时使用7位地址
	I2C_InitStructure.I2C_OwnAddress1 = 0x00;//若stm32作为从机时的地址
	I2C_Init(I2C2,&I2C_InitStructure);
	
	I2C_Cmd(I2C2,ENABLE);
}

void I2C_Master_Write(uint8_t addr,uint8_t *data,int length) {
	I2C_GenerateSTART(I2C2,ENABLE);
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT);//EV5事件，起始条件已发送
	I2C_Send7bitAddress(I2C2,addr,I2C_Direction_Transmitter);
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//EV6事件，地址已发送并接收到应答
	while(length > 0) {
		I2C_SendData(I2C2,*data);
		data++;
		length--;
		if(length == 0) {
			I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED);//EV8_2事件，移位寄存器已发完且DR也为空
		} else {
			I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTING);//EV8事件，字节已转入移位寄存器，数据寄存器DR为空并等待新的数据写入
		}
	}
	I2C_GenerateSTOP(I2C2,ENABLE);
}

void I2C_Soft_Master_Write(uint8_t addr,uint8_t *data,int length) {
	I2C_Soft_Start();
	I2C_Soft_SendByte(addr); //1101 000 0
	I2C_Soft_ReceiveAck();
	while(length > 0) {
		I2C_Soft_SendByte(*data);
		I2C_Soft_ReceiveAck();
		data++;
		length--;
	}
	I2C_Soft_Stop();
}

void I2C_Master_Read(uint8_t addr,uint8_t *recBuffer,int length) {
	I2C_GenerateSTART(I2C2,ENABLE);
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_MODE_SELECT);//EV5事件，起始条件已发送
	I2C_Send7bitAddress(I2C2,addr,I2C_Direction_Receiver);
	I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);//EV6事件，地址已发送并接收到应答
	while(length > 0) {
		if(length == 1) {
			I2C_AcknowledgeConfig(I2C2,ENABLE);//接收最后一个字节之前，要提前设置非应答和停止
			I2C_GenerateSTOP(I2C2,ENABLE);
		}
		I2C_WaitEvent(I2C2,I2C_EVENT_MASTER_BYTE_RECEIVED);
		*recBuffer = I2C_ReceiveData(I2C2);
		recBuffer++;
		length--;
	}
	I2C_AcknowledgeConfig(I2C2,ENABLE);
}

void I2C_Soft_Master_Read(uint8_t addr,uint8_t *recBuffer,int length) {
	I2C_Soft_Start();
	I2C_Soft_SendByte(addr | 0x01);
	I2C_Soft_ReceiveAck();
	while(length > 0) {
		*recBuffer = I2C_Soft_ReceiveByte();
		recBuffer++;
		length--;
		if(length == 0) {
			I2C_Soft_SendAck(1); //不想继续读了就给非应答
		} else {
			I2C_Soft_SendAck(0);
		}
	}
	I2C_Soft_Stop();
}
